<!--
 * @Author: chunlai
 * @Date: 2024-08-28 14:02:55
 * @LastEditTime: 2025-11-24 09:32:39
 * @LastEditors: minsheng_insurance_agency_zhoucl
 * @FilePath: \01.latest-short-insure\src\views\form\components\VerifyCode.vue
 * @Description: 验证码倒计时
-->
<template>
  <div
    class="verify_code_btn"
    :class="canGetCode ? 'active' : ''"
    @click="sendCode"
  >
    {{ smsText || "获取验证码" }}
  </div>
</template>

<script>
export default {
  name: "VerifyCode",
  props: {
    phone: {
      type: String,
      default: () => "",
    },
    seconds: {
      type: [String, Number],
      default: 60,
    },
  },
  components: {},
  data() {
    return {
      secNum: this.seconds,
      timer: null,
      startText: "获取验证码",
      changeText: "X秒后获取",
      endText: "重新获取",
      smsText: "",
      canGetCode: true,
      keepRunning: true,
    };
  },
  computed: {},
  watch: {
    seconds: {
      immediate: true,
      handler(n) {
        this.secNum = n;
      },
    },
  },
  created() {},
  mounted() {
    this.checkKeepRunning();
  },
  beforeDestroy() {
    this.setTimeToStorage();
    clearTimeout(this.timer);
    this.timer = null;
  },
  methods: {
    checkKeepRunning() {
      // // 获取上一次退出页面(H5还包括刷新)时的时间戳，如果没有上次的保存，此值可能为空
      let lastTimestamp = Number(
        localStorage.getItem("_$msCountDownTimestamp")
      );
      if (!lastTimestamp) return this.changeEvent(this.startText);
      // 当前秒的时间戳
      let nowTimestamp = Math.floor(+new Date() / 1000);
      // 判断当前的时间戳，是否小于上一次的本该按设定结束，却提前结束的时间戳
      if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
        // 剩余尚未执行完的倒计秒数
        this.secNum = lastTimestamp - nowTimestamp;
        console.log("checkKeepRunning", this.secNum);
        // 清除本地保存的变量
        localStorage.removeItem("_$msCountDownTimestamp");
        // 开始倒计时
        this.countDownStart();
      } else {
        // 如果不存在需要继续上一次的倒计时，执行正常的逻辑
        this.changeEvent(this.startText);
      }
    },
    sendCode() {
      if (!this.phone) return this.$toast("请输入手机号");
      if (!this.canGetCode) return;
      let params = {
        mainRiskCode: this.mainRiskCode,
        workNum: this.workNum,
        phone: this.phone,
      };
      this.$store
        .dispatch("apis/comAdminApiRequest", {
          apiParams: params,
          apiName: "aquireShortMsg",
          toast: true,
        })
        .then((data) => {
          this.countDownStart();
          this.$toast("发送成功,请注意查收");
        });
    },
    countDownStart() {
      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      }
      this.canGetCode = false;
      this.changeEvent(this.changeText.replace(/x|X/, this.secNum));
      this.setTimeToStorage();
      this.timer = setInterval(() => {
        if (--this.secNum) {
          this.changeEvent(this.changeText.replace(/x|X/, this.secNum));
        } else {
          this.reset();
        }
      }, 1000);
    },
    changeEvent(text) {
      this.smsText = text;
    },
    setTimeToStorage() {
      if (!this.keepRunning || !this.timer) return;
      // 记录当前的时间戳，为了下次进入页面，如果还在倒计时内的话，继续倒计时
      // 倒计时尚未结束，结果大于0；倒计时已经开始，就会小于初始值，如果等于初始值，说明没有开始倒计时，无需处理
      if (this.secNum > 0 && this.secNum <= this.seconds) {
        // 获取当前时间戳(+ new Date()为特殊写法)，除以1000变成秒，再去除小数部分
        let nowTimestamp = Math.floor(+new Date() / 1000);
        // 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
        localStorage.setItem(
          "_$msCountDownTimestamp",
          nowTimestamp + Number(this.secNum)
        );
      }
    },
    reset() {
      clearInterval(this.timer);
      this.timer = null;
      this.canGetCode = true;
      this.secNum = this.seconds;
      this.changeEvent(this.endText);
    },
  },
};
</script>
<style lang="less" scoped>
.verify_code_btn {
  display: inline-block;
  width: 76px;
  height: 28px;
  line-height: 28px;
  font-weight: 500;
  font-size: 12px;
  color: #909399;
  text-align: center;
  cursor: pointer;
  border-radius: 4px;
  background: #f4f4f5;
  border: 1px solid #d3d4d6;
  &.active {
    color: #fff;
    background: #409eff;
    border: 1px solid #409eff;
  }
}
</style>
